﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Thread = System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Infrastucture;
using TimeSplicerModule.Factories;
using TimeSplicerModule.DomainModels;
using TimeSplicerModule.Security;
using TimeSplicerModule.ViewModels;

namespace TimeSplicerModule.Services
{
    public partial class TaskService : ITaskService
    {
        public TaskModel CreateNew(Guid projectGuid)
        {
            _session = _container.Resolve<ISession>();
            var p = _projectService.Get(projectGuid);

            var statuses = _session.Statuses; //_statusFactory.GetList();
            var users = _userFactory.GetList(); 
            var projectRoles = _projectRoleFactory.GetList();
            
            // will need to do some limiting 

            var model = new TaskModel();
            model.ProjectGuid = projectGuid;
            model.Project = p;
            model.Priorities = _session.Priorities; //_priorityFactory.GetList();

            // need to get only viable categories
            var categories = _categoryService.GetSelectableCategories();

            model.Categories = categories.Where(x => x.IsTaskCategory).ToList();
            model.SubCategories = categories.Where(x => x.IsTaskSubCategory).ToList();

            // now oroject uses set by project role
            var role = p.ProjectUsers.FirstOrDefault(x => x.UserGuid == _session.User.UserGuid);

            if (role.ProjectRole.Hierarchy == 1)
            {
                model.ProjectUsers = p.ProjectUsers; //_projectUserFactory.GetList(users, projectRoles).Where(x => x.ProjectGuid == projectGuid).ToList();
            }
            else if (role.ProjectRole.Hierarchy > 0)
            {
                model.ProjectUsers = p.ProjectUsers.Where(x => x.UserGuid == _session.User.UserGuid).ToList();
            }



            // set defaults
            model.CreatedDate = DateTime.Now;
            model.CreatedBy = _session.User;
            model.DueDate = DateTime.Now.AddDays(1);
            model.PriorityGuid = model.Priorities.FirstOrDefault(x => x.Priority == Priority.Normal).PriorityGuid;
            model.Status = statuses.FirstOrDefault(x => x.Status == Status.Not_Started);
            model.StatusGuid = model.Status.StatusGuid;
            model.AssignedToGuid = _session.User.UserGuid; //model.ProjectUsers.FirstOrDefault().UserGuid;
            model.Schedule = new TaskScheduleModel();

            return model;
        }

        public List<TaskModel> GetMyTasks()
        {
            _session = _container.Resolve<ISession>();



            throw new NotImplementedException();
        }

        public List<TaskModel> GetTasks(UserModel user)
        {
            _session = _container.Resolve<ISession>();

            var projects = _projectService.GetList(user);
            var statuses = _session.Statuses; //_statusFactory.GetList();
            var priorities = _session.Priorities; //_priorityFactory.GetList();
            var categories = _categoryFactory.GetList();
            var tasks = _taskFactory.GetList(x => x.AssignedToGuid == user.UserGuid);

            foreach (var t in tasks)
            {
                t.Project = projects.FirstOrDefault(x => x.ProjectGuid == t.ProjectGuid);
                t.Status = statuses.FirstOrDefault(x => x.StatusGuid == t.StatusGuid);
                t.Priority = priorities.FirstOrDefault(x => x.PriorityGuid == t.PriorityGuid);
                t.Category = categories.FirstOrDefault(x => x.CategoryGuid == t.CategoryGuid);
                t.SubCategory = categories.FirstOrDefault(x => x.CategoryGuid == t.SubCategoryGuid);
                t.Timestamps = _timestampService.GetList(t);
            }

            return tasks;
        }

        public List<TaskModel> GetTasks(ProjectModel project, UserModel user)
        {
            _session = _container.Resolve<ISession>();

            var statuses = _session.Statuses; //_statusFactory.GetList();
            var categories = _categoryFactory.GetList();
            var tasks = _taskFactory.GetList(x => x.ProjectGuid == project.ProjectGuid
                && x.AssignedToGuid == user.UserGuid);


            foreach (var t in tasks)
            {
                t.Status = statuses.FirstOrDefault(x => x.StatusGuid == t.StatusGuid);
                t.Category = categories.FirstOrDefault(x => x.CategoryGuid == t.CategoryGuid);
                t.SubCategory = categories.FirstOrDefault(x => x.CategoryGuid == t.SubCategoryGuid);
                t.Timestamps = _timestampService.GetList(t);
            }

            return tasks;
        }

        public List<ProjectModel> GetList(List<UserModel> users)
        {
            _session = _container.Resolve<ISession>();

            var statuses = _statusFactory.GetList();
            var categories = _categoryFactory.GetList();
            List<ProjectModel> projects = new List<ProjectModel>();
           

            foreach (var u in users)
            {
                var tasks = new List<TaskModel>();

            }

            throw new NotFiniteNumberException();
        }

        public TaskModel GetInProgressTask()
        {
            _session = _container.Resolve<ISession>();

            var inProgress = _session.Statuses.FirstOrDefault(x => x.StatusEnum == Status.In_Progress.ToString()); //_statusFactory.Get(x => x.StatusEnum == Status.In_Progress.ToString());
            var inProgressTask = _taskFactory.Get(x => x.AssignedToGuid == _session.User.UserGuid
                && x.StatusGuid == inProgress.StatusGuid);

            if (inProgressTask == null)
                return null;
            

            var task = Get(inProgressTask.TaskGuid);
            var model = ModelConverter.ToModel<TaskModel>(task);

            return model;
        }


        public List<TaskModel> GetTaskListByWorkedOnDateRange(UserModel user, daterange range)
        {
            List<TaskModel> workedOnTasks = new List<TaskModel>();
            var tasks = _taskFactory.GetList(x => x.AssignedToGuid == user.UserGuid);
            
            // get timestamps foreach
            foreach (var t in tasks)
            {
                t.Timestamps = _timestampService.GetList(t);

                var stampsInRange = t.Timestamps.Where(x => x.StartTime >= range.StartDate
                    && x.StartTime <= range.EndDate).ToList();

                if (stampsInRange.Count > 0)
                    workedOnTasks.Add(t);
            }

            return workedOnTasks;
        }
    }
}
